-- Jeroen Langelaan & Jens Zonneveld
-- 03-02-2012
-- Versie 1.0

-- Dit gedeelte berekend de aansturing van de verschillende RAM geheugens
-- aan de hand van de x- en y-teller vanuit de VGA timing.
-- De verschillende delen van het RAM moeten op een vooraf bepaalde positie komen.
-- Dit wordt hier uitgerekend en aan de hand daarvan de juiste aansturing voor het RAM geheugen.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity calcul is
	port( x_teller, y_teller : in integer range 0 to 1023;
			read_dataid : in std_logic_vector(5 downto 0); -- Read data voor ID-RAM
			read_addrid : out std_logic_vector(7 downto 0); -- Read adres voor ID-RAM
			read_addrspr : out std_logic_vector(11 downto 0);
			sprite_on : out std_logic
			);	 -- Read adres voor Sprite-RAM 
end calcul;

architecture Behavioral of calcul is

	-- Deze signals helpen bij het neerzetten van het speelveld op het scherm
	-- x- en y_tellerh3 zorgen ervoor dat de tellers op 0 beginnen als de gewenste positie is bereikt(160,68)
	-- x- en y_tellerh slaan het omgezette integer op.
	-- x- en y_tellerh2 halen de 4 LSB's van h weg. Dit gebeurd omdat er om de 16 pixels een nieuw plaatje moet worden neergezet.
	-- Zo worden de h2 signalen 'tellers' die elke 16 pixels 1 ophogen.
	
	signal x_tellerh : std_logic_vector(9 downto 0); 
	signal x_tellerh2 : std_logic_vector(4 downto 0);
	signal x_tellerh3 : integer range 0 to 1023;
	
	signal y_tellerh : std_logic_vector(9 downto 0);
	signal y_tellerh2 : std_logic_vector(4 downto 0);
	signal y_tellerh3 : integer range 0 to 1023;
	
begin
	-- In dit process wordt bepaald wanneer het speelveld is bereikt en worden de h3 signalen op de goede waarde gezet.
	-- Zie de conversies rond regel 70.
	process(x_teller, y_teller)
	begin
	
		if (x_teller >= 160 and x_teller < 320 and y_teller >= 68 and y_teller < 420) then
			x_tellerh3 <= x_teller - 160;
			y_tellerh3 <= y_teller - 68;
			if x_teller > 162 then sprite_on <= '1'; end if;		
	
		else x_tellerh3 <= 0; 
		  y_tellerh3 <= 0;
		  sprite_on <= '0';
		end if;
	end process;
	
	-- In dit process wordt er bepaald bij welk blokje van het speelveld de tellers nu zijn.
	-- Dit gebeurd aan de hand van de h2 'tellers'.
	-- Aan de hand hiervan kan uitgerekend worden welk adres van het ID-ram moet worden aangestuurd.
	process(x_tellerh2, y_tellerh2)
	
	variable y_maal : integer range 0 to 31;
	variable x_maal : integer range 0 to 15;
	variable readaddr : integer range 0 to 255;
	
	begin
		x_maal := to_integer(unsigned(x_tellerh2)); -- Conversie zodat ermee gerekend kan worden
		y_maal := to_integer(unsigned(y_tellerh2)); -- Conversie zodat ermee gerekend kan worden
		
		readaddr := (10 * y_maal) + x_maal; -- Zet de tellers om in een read_addr.
		
		read_addrid <= std_logic_vector(to_unsigned(readaddr,8)); -- Read addr is een std_logic_vector
		
	end process;
	
	-- Conversies van de verchillende signal, zie uitleg boven
	x_tellerh <= std_logic_vector(to_unsigned(x_tellerh3,10));
	x_tellerh2 <= x_tellerh(8 downto 4);
	
	y_tellerh <= std_logic_vector(to_unsigned(y_tellerh3,10));
	y_tellerh2 <= y_tellerh(8 downto 4);
	
	-- Het read adres van de sprites is afhankelijk van het gelezen id en de positie van de tellers IN een blokje.
	-- Het laatste bit valt weg omdat de sprite moet worden uitgerekt.
	read_addrspr <= read_dataid  & y_tellerh(3 downto 1)& x_tellerh(3 downto 1);
	
	
end Behavioral;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

package calcpack is

component calcul is
	port( x_teller, y_teller : in integer range 0 to 1023;
			read_dataid : in std_logic_vector(5 downto 0);
			read_addrid : out std_logic_vector(7 downto 0);
			read_addrspr : out std_logic_vector(11 downto 0);
			sprite_on : out std_logic);	
end component;

end calcpack;